/*
 * Modbus app for RTU.
 * Copyright (c) 2012  apleilx
 * All rights reserved.
 * no limite
 */

/* ----------------------- Platform includes --------------------------------*/
#define _MAPP_MODULE_
#include "mbapp.h"
#include "os_obj.h" // RTOS object definitions
#include "sys_task.h"
#include "sys_init.h"
#include "common.h"

#define TEST_MODE MB_RTU_SLAVE

mb_baud_tab_create;

uint8_t mbTestErrCnt = 0;
uint8_t mbTestOkCnt = 0;

typedef struct
{
	uint16_t reg_r[64];
	uint16_t reg_w[64];
	uint16_t pv_r[64];
	uint16_t pv_w[64];
	uint16_t obj_size;
} mb_tst_type;

mb_tst_type mb_tst;

void rcv_end_handle_comp(uint8_t ErrSt);
void qc_task(const void *argv);
void modbus_task(const void *argv);

/******************************************************************************
 * @brief   modbus task creat.
 * @param   argv
 * @return  none
 * @ Pass/ Fail criteria: none
 *****************************************************************************/
osThreadDef(thd_mb, modbus_task, osPriorityNormal, 0, 0x400);
void mb_task_creat(void)
{
	os_obj.tid_mb_task = osThreadCreate(osThread(thd_mb), NULL);
}
obj_init_order5(mb_task_creat);

/******************************************************************************
 * @brief   modbus task.
 * @param   argv
 * @return  none
 * @ Pass/ Fail criteria: none
 *****************************************************************************/
void modbus_task(const void *argv)
{
	qc_task(argv);
}

/******************************************************************************
 * @brief   mb handle.
 * @param   none
 * @return  none
 * @ Pass/ Fail criteria: none
 *****************************************************************************/
void qc_callback(uu8 site, uu8 err)
{
	if (err)
	{
		mb.err_val = err;
	}
}
void qc_task(const void *argv)
{
	qc_cmd_type mcmd;
	uu8 bdone;

	// master config
	// qc01_Init(QC_MODE_MASTER, 115200);
	// mb.qc01.os_event_send = mb_os_send;
	// mb.qc01.et_sv = 200;
	// mb.qc01.tout_sv = 240;

	// master config
	qc08_Init(QC_MODE_MASTER, 115200, MB_PAR_NONE);
	mb.qc08.os_event_send = mb_os_send;

	// master config
	qc03_Init(QC_MODE_SLAVE, 115200, MB_PAR_NONE);
	mb.qc03.os_event_send = mb_os_send;

	// cmd config
	mcmd.id = 1;
	mcmd.wdat = mb_tst.pv_w;
	mcmd.rdat = mb_tst.pv_r;
	mcmd.wa = word_make(0, 4);
	mcmd.wn = 4;
	mcmd.ra = word_make(0x00, 0x10);
	mcmd.rn = 6;
	mcmd.callback = qc_callback;
	mcmd.attr = QC_MB_ATTR_HOLD_RW;
	mqc_stc_cmd_req(&mb.qc03, 0, &mcmd);
	mqc_stc_cmd_req(&mb.qc08, 0, &mcmd);

	mcmd.wa = word_make(0x10, 12);
	mcmd.wn = 0;
	mqc_stc_cmd_req(&mb.qc03, 1, &mcmd);
	mqc_stc_cmd_req(&mb.qc08, 1, &mcmd);

	mcmd.wa = word_make(0, 8);
	mcmd.wn = 8;
	mcmd.ra = word_make(0x0C, 8);
	mcmd.rn = 8;
	mcmd.wdat = mb_tst.reg_w;
	mcmd.rdat = mb_tst.reg_r;
	mcmd.attr = QC_MB_ATTR_HOLD_RW;
	mb.qc03.fun->stc_cmd_req(2, &mcmd);
	mb.qc08.fun->stc_cmd_req(2, &mcmd);

	mqc_dyna_cmd_req(&mb.qc03, &mcmd);
	mqc_dyna_cmd_req(&mb.qc08, &mcmd);
	mqc_dyna_cmd_req(&mb.qc03, &mcmd);
	mqc_dyna_cmd_req(&mb.qc08, &mcmd);

	loop(32) mb_tst.reg_w[index] = index;
	mb_tst.reg_w[0] = 0x5588;

	// task handle
	for (;;)
	{

		tx_semaphore_get(os_obj.sid_mb, ms_ticks(1000));

		loop(32)
			mb_tst.reg_w[index] += index;

		qc_mb_poll(&mb.qc03);
		qc_mb_poll(&mb.qc08);

		// qc_poll(&mb.qc03);
		// qc_poll(&mb.qc08);

		mb_tst.obj_size = sizeof(mb.qc03);

		if ((mb.qc08.success_cnt & 0x3) == 0)
		{
			if (!bdone)
			{
				bdone = 1;
				mqc_dyna_cmd_req(&mb.qc03, &mcmd);
				mqc_dyna_cmd_req(&mb.qc08, &mcmd);
			}
		}
		else
		{
			bdone = 0;
		}

		if (mb.qc08.master.st_cmd_empty)
		{
			mqc_dyna_cmd_req(&mb.qc03, &mcmd);
			mqc_dyna_cmd_req(&mb.qc08, &mcmd);
			mqc_dyna_cmd_req(&mb.qc03, &mcmd);
			mqc_dyna_cmd_req(&mb.qc08, &mcmd);
		}
	}
}
